﻿using Network.Extension;
using Network.FrameSync;
using Network.General.Server;
using Network.Utils;
using System.Collections.Generic;
using System.Text;

public class Room
{
    private static uint _lastRid = 0;
    public static uint NewRoomID()
    {
        return ++_lastRid;
    }

    private RoomData _data;
    public RoomData data { get { return _data; } }

    private DictionarySafe<uint, ISession> _mapSession;

    public override string ToString()
    {
        return string.Format("<data:{0}, sessions:{1}>", _data, _mapSession.ToListString());
    }

    public string DumpString(string prefix = "")
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendFormat("<id:{0}, name:{1}, owner:{2}, players_count:{3}>\n", _data.id, _data.name, _data.owner, _data.players.Count);

        sb.AppendLine(prefix + "\tPlayerList:");
        for (int i = 0; i < _data.players.Count; i++)
        {
            sb.AppendLine(prefix + "\t" + _data.players[i].ToString());
        }

        sb.AppendLine(prefix + "\tSessionList:");
        foreach (var session in _mapSession)
        {
            sb.AppendLine(prefix + "\t" + session.Value.ToString());
        }

        return sb.ToString();
    }

    public void Create(uint userId, string userName, ISession session, string roomName)
    {
        _mapSession = new DictionarySafe<uint, ISession>();

        _data = new RoomData();
        _data.id = NewRoomID();
        _data.name = roomName;
        _data.owner = userId;

        _data.ip = UserManager.Instance.IP;
        _data.port = UserManager.Instance.Port;
        _data.maxPlayers = 2;

        AddPlayer(userId, userName, session);
    }

    public void AddPlayer(uint userId, string userName, ISession session)
    {
        PlayerData data = GetPlayerInfoByUserId(userId);
        if (data == null)
        {
            data = new PlayerData();
            //data.id = (uint)_data.players.Count;
            data.id = userId; // 使用userId作为playerId
            data.sid = session.Id;

            _data.players.Add(data);
        }
        data.isReady = false;
        data.userId = userId;
        data.name = userName;

        _mapSession[userId] = session;
    }

    public void RemovePlayer(uint userId)
    {
        int i = GetPlayerIndexByUserId(userId);
        if (i >= 0)
        {
            _data.players.RemoveAt(i);
        }

        _mapSession.Remove(userId);

        if (userId == _data.owner)
        {
            if (_data.players.Count > 0)
            {
                _data.owner = _data.players[0].userId;
            }
        }
    }

    public int GetPlayerCount()
    {
        return _data.players.Count;
    }

    private int GetPlayerIndexByUserId(uint userId)
    {
        for (int i = 0; i < _data.players.Count; i++)
        {
            if (_data.players[i].userId == userId)
            {
                return i;
            }
        }
        return -1;
    }

    private PlayerData GetPlayerInfoByUserId(uint userId)
    {
        for (int i = 0; i < _data.players.Count; i++)
        {
            if (_data.players[i].userId == userId)
            {
                return _data.players[i];
            }
        }
        return null;
    }

    public ISession[] GetSessionList()
    {
        List<ISession> list = new List<ISession>();
        for (int i = 0; i < _data.players.Count; i++)
        {
            uint userId = _data.players[i].userId;
            list.Add(_mapSession[userId]);
        }

        return list.ToArray();
    }

    public ISession GetSession(uint userId)
    {
        return _mapSession[userId];
    }

    public bool CanStartGame()
    {
        if (_data.players.Count >= 1 && IsAllReady())
        {
            return true;
        }
        return false;
    }

    public bool IsAllReady()
    {
        bool isAllReady = true;
        for (int i = 0; i < _data.players.Count; i++)
        {
            if (!_data.players[i].isReady)
            {
                isAllReady = false;
                break;
            }
        }
        return isAllReady;
    }

    public void SetReady(uint userId, bool value)
    {
        var info = GetPlayerInfoByUserId(userId);
        if (info != null)
        {
            info.isReady = value;
        }
    }

    public FSPParam GetGameStartParam()
    {
        FSPParam param = new FSPParam();
        return param;
    }
}